package vn.edu.saigontech.ncms.model.result;

import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
import javax.persistence.Transient;

@Entity
@DiscriminatorValue("cambridge_test")
@SuppressWarnings("serial")
public class CambridgeTest extends AbstractTest {

	public static final double WRITTEN_WEIGHT = 0.4;
	public static final double ORAL_WEIGHT = 0.2;

	@Transient
	public Double getWrittenScore() {
		try {
			GradeDetail gradeDetail = this.getGradeDetail();
			double totalWritten = gradeDetail.computeTotalWritternScore(this);
			if ((totalWritten % 0.5) == 0)
				return totalWritten;
			return (double) Math.round(totalWritten);
		} catch (Exception ex) {
		}
		return null;
	}
	
	/**
	 * get the grade detail from the offering class
	 * 
	 * @return
	 */
	private GradeDetail getGradeDetail() {
		return this.getOfferingMember().getReceipt().getOffering()
				.getFinalGradeDetail();
	}

	@Transient
	public Double getConvertedWrittenScore() {
		Double total = this.getWrittenScore();
		if (total == null)
			return null;
		return total * WRITTEN_WEIGHT;
	}

	@Transient
	public Double getOralScore() {
		try {
			if ((this.speaking % 0.5) == 0)
				return this.speaking;
			return (double) Math.round(this.speaking);
		} catch (Exception ex) {
		}
		return null;
	}

	@Transient
	public Double getConvertedOralScore() {
		Double total = this.getOralScore();
		if (total == null)
			return null;
		return total * ORAL_WEIGHT;
	}

	public boolean oldPassed() {
		Grade grade = this.getOldGrade();
		return grade != null && !Grade.F.equals(grade);
	}

	@Transient
	public Grade getOldGrade() {
		Double total = this.getOldTotal();
		if (total == null)
			return null;
		if (total >= 90 && total <= 100) {
			return Grade.A;
		} else if (total >= 80 && total < 90) {
			return Grade.B;
		} else if (total >= 70 && total < 80) {
			return Grade.C;
		} else if (total >= 60 && total < 70) {
			return Grade.D;
		} else if (total >= 0 && total < 60) {
			return Grade.F;
		}
		return null;
	}

	public Double getTotal() {
		return this.getConvertedWrittenScore() + this.getConvertedOralScore();
	}

	@Transient
	public Double getOldTotal() {
		try {
			double total = this.listening + this.speaking + this.reading
					+ this.writing;
			if ((total % 0.5) == 0)
				return total;
			return (double) Math.round(total);
		} catch (Exception ex) {
		}
		return null;
	}
	
	/**
	 * to check whether all grade has been input
	 * @return
	 */
	public boolean isAllGradeInput() {
		boolean ret = true;
		if (listening == null || grammar == null || speaking == null
				|| reading == null || writing == null) {
			ret = false;
		}
		return ret;
	}

	/**
	 * to check whether there is any grade has been input
	 * @return
	 */
	public boolean isAnyGradeInput() {
		boolean ret = false;
		if (listening != null || grammar != null || speaking != null
				|| reading != null || writing != null) {
			ret = true;
		}
		return ret;
	}
}